Skip to content

Added setXXX methods to change used pins of an instance #193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 11, 2018

Conversation

fpistm
Copy link
Member

@fpistm fpistm commented Jan 9, 2018

Example to change pins used by Wire instance (by default use defined SDA/SCL ):

Wire.setSDA(A4);
Wire.setSCL(PC2);
Wire.begin();

Example to change pins used by SPI instance (by default use defined MISO/MOSI/SCK):

SPI.setMOSI(22);
SPI.setMISO(PA3);
SPI.begin();

@fpistm fpistm added the enhancement New feature or request label Jan 9, 2018
@fpistm fpistm added this to the Next release milestone Jan 9, 2018
@fpistm fpistm self-assigned this Jan 9, 2018
@romainreignier
Copy link

That change seems very helpful but it there any mechanism to check if the selected pin has the right capability?

@fpistm
Copy link
Member Author

fpistm commented Jan 10, 2018

Pins capabilities are checked during the begin() and print an error message.
For SPI:

if(spi_mosi == NP || spi_miso == NP || spi_sclk == NP) {

For I2C:
if(i2c_sda == NP || i2c_scl == NP) {

Unfortunately the standard API begin() from Arduino do not return any value.
Mainly up to the user to ensure pins used have the right capabilities.

Note: Init check also that all pins are linked to the same peripheral.

@mayukhIITD
Copy link

Yes I would agree to @romainreignier .. For example in my case I needed to set the SDA SCL pins to A4,A5.. But I am not able to do that.. Because I am using IKSA102 board for temperature,Humidity,Pressure sensing which uses I2C and is probably using either of A4,A5.. Hence when I set SDA SCL pins to A4,A5 ,I am getting wrong values for Temperature and Humidity..

@fpistm
Copy link
Member Author

fpistm commented Jan 10, 2018

@mayukhIITD
If you need several pins to I2C you have to instantiate a new Wire instance.
Main issue could come from Arduino libraries which use the standard Wire instance.
I you use 2 libraries using this instance, you have to modify the library to use a different instance.

@romainreignier
Copy link

@fpistm Ah, that's great that the pins are being checked but it is at runtime and the user need a serial console opened, right?

It would be nice to check at compile time with static_assert but will prevent to change the pins on the fly :(
But if it is possible to instantiate several instances of the peripherals, it may be done.

@fpistm
Copy link
Member Author

fpistm commented Jan 10, 2018

Yes, right.
Core could not check all possible use case.
As the main goal of this core is to be generic for all STM32 MCU, it's quite hard to perform this kind of check at compile time. Peripherals linked to a pin are stored in several arrays in PeripheralPins.c

@romainreignier
Copy link

Ok, I see.

But anyway, this change is great and will ease the usage of these peripherals 👍

@lacklustrlabs
Copy link
Contributor

I was playing around with compile-time checks on Wire.setSDA() and Wire.SDL(), this is what I came up with:

Wire.h:

   ....
    void setSDA(PinName sda) { _i2c.sda = sda; };
   + 
   +template <uint32_t scl>
   +void setSCL() {
   +	  static_assert(digitalPinHasI2CSCL(scl), "SCL must be a supported pin");
   +	  _i2c.scl = digitalPinToPinName(scl); 
   +};
   +
   + template <uint32_t sda>
   + void setSDA() { 
   +	  static_assert(digitalPinHasI2CSDA(sda), "SDA must be a supported pin");
   +  	  _i2c.sda = digitalPinToPinName(sda); 
   +  };
        
    void begin();
    ... 

variant.h:

...
+constexpr bool digitalPinHasI2CSCL(uint32_t scl) {
+  return scl==1||scl==14||scl==11; // just an example
+}

+constexpr bool digitalPinHasI2CSDA(uint32_t sda) {
+  return sda==2||sda==15||sda==11; // just an example
+}

#endif /*  __cplusplus */


#endif /* _VARIANT_ARDUINO_STM32_ */

The.ino

...
void setup()
{
  +Wire.setSCL<1>();
  +Wire.setSDA<2>();
  Wire.begin(); // join i2c bus (address optional for master)
}
....

This would require some work to manually edit each variant.h (add the I2C & SPI constexpr functions)

Disclamer: I've only tested that it compiles

@fpistm
Copy link
Member Author

fpistm commented Jan 10, 2018

Nice code snippets ;)
I think it's too much work for no real benefits.
pins are hardcoded, while the pin mapping allows to get capabilities dynamically qnd depending on the PeripheralPins config the capabilities could be enabled or not.
This is customizable by the user so the risk is to add some misalignement.

const PinMap PinMap_I2C_SDA[] = {
//  {PB_7,   I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)},
    {PB_9,   I2C1, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C1)}, // D14
//  {PB_11,  I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
//  {PC_9,   I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
//  {PD_13,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C4)},
//  {PF_0,   I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
//  {PF_15,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C4)},
//  {PH_5,   I2C2, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C2)},
//  {PH_8,   I2C3, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C3)},
//  {PH_12,  I2C4, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_NOPULL, GPIO_AF4_I2C4)},
    {NC,    NP,    0}
};

anyway, User has to know which pins are used for the wiring of it's I2C device.

@LMESTM
Copy link
Member

LMESTM commented Jan 10, 2018

agree with @fpistm - compile time check looks a bit overkill to me. What really matters is that user correctly check schematics and wiring of the hardware board - that's usually were most encountered errors comes from ...

Example to change pins used by Wire instance (by default use defined SDA/SCL ):
Wire.setSDA(A4);
Wire.setSCL(PC2);
Wire.begin();

Example to change pins used by SPI instance (by default use defined MISO/MOSI/SCK):
SPI.setMOSI(22);
SPI.setMISO(PA3);
SPI.begin();

Signed-off-by: Frederic.Pillon <frederic.pillon@st.com>
@fpistm fpistm merged commit 390deaf into stm32duino:master Jan 11, 2018
@fpistm fpistm deleted the setXX branch January 11, 2018 16:02
benwaffle pushed a commit to benwaffle/Arduino_Core_STM32 that referenced this pull request Apr 10, 2019
Added setXXX methods to change used pins of an instance
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants